ভিএম প্যাকেজের পরিচিতি
VM (ভার্চুয়াল মেশিন) মডিউল আপনাকে বিচ্ছিন্ন পরিবেশে কোড কম্পাইল এবং চালানোর অনুমতি দেয়।
এটি এর জন্য দরকারী:
নিরাপদে অবিশ্বস্ত কোড চলমান
একটি স্যান্ডবক্সে নিরাপদে অবিশ্বস্ত কোড চলছে৷
গতিশীলভাবে জাভাস্ক্রিপ্ট কোড মূল্যায়ন
গতিশীলভাবে জাভাস্ক্রিপ্ট কোড মূল্যায়ন
প্লাগইন এবং এক্সটেনশন সিস্টেম তৈরি করা
প্লাগইন এবং এক্সটেনশন সিস্টেম তৈরি করা
কাস্টম স্ক্রিপ্টিং পরিবেশ কনফিগার করা হচ্ছে
কাস্টম স্ক্রিপ্টিং পরিবেশ কনফিগার করা হচ্ছে
বিচ্ছিন্নভাবে পরীক্ষার কোড
বিচ্ছিন্নভাবে পরীক্ষার কোড
সতর্কতা:
যদিও VM মডিউল প্রধান জাভাস্ক্রিপ্ট পরিবেশ থেকে বিচ্ছিন্নতা প্রদান করে, এটি একটি সম্পূর্ণ নিরাপদ স্যান্ডবক্স নয়। অবিশ্বস্ত কোড চালানোর জন্য এটি একমাত্র নিরাপত্তা ব্যবস্থা হিসাবে ব্যবহার করা উচিত নয়।
একটি VM প্যাকেজ আমদানি করা হচ্ছে
VM প্যাকেজ ব্যবহার করার জন্য, আপনার Node.js অ্যাপ্লিকেশনে এটির প্রয়োজন হবে:
const vm = require('vm');
মূল ধারণা
ভিএম মডিউলটিতে বেশ কয়েকটি মূল উপাদান রয়েছে:
| বল | ব্যাখ্যা |
|---|---|
| Script | কম্পাইল করা জাভাস্ক্রিপ্ট কোড যা বিভিন্ন পরিবেশে একাধিকবার চালানো যেতে পারে |
| Context | একটি বিচ্ছিন্ন গ্লোবাল অবজেক্ট যেখানে স্ক্রিপ্ট চালানো হয় একটি স্যান্ডবক্সড পরিবেশের মতো |
| ContextifiedObject | একটি VM পরিবেশের সাথে যুক্ত একটি অবজেক্ট এবং এটির গ্লোবাল অবজেক্ট হিসাবে কাজ করে |
বেসিক অ্যাপ্লিকেশন: একটি পরিবেশে জাভাস্ক্রিপ্ট চালানো
একটি VM প্যাকেজ ব্যবহার করার সবচেয়ে সহজ উপায় হল একটি পরিবেশে কোড চালানো:
const vm = require('vm');
// Create a context object
const context = { x: 2 };
// Compile and run a script in the context
vm.createContext(context);
vm.runInContext('x = x * 2; y = 10;', context);
// Inspect the modified context
console.log(context); // Outputs: { x: 4, y: 10 }
এই উদাহরণে:
ভিএম প্যাকেজ পদ্ধতি
স্ক্রিপ্ট পদ্ধতি
| পদ্ধতি | ব্যাখ্যা |
|---|---|
| vm.Script(code[, options]) | একটি নতুন স্ক্রিপ্ট অবজেক্ট তৈরি করে যা কম্পাইল করা কোডকে উপস্থাপন করে |
| script.runInContext(contextObject[, options]) | একটি নির্দিষ্ট পরিবেশে সংকলিত কোড চালায় |
| script.runInNewContext([contextObject][, options]) | একটি নতুন পরিবেশে সংকলিত কোড চালায় |
| script.runInThisContext([options]) | বর্তমান প্রেক্ষাপটে সংকলিত কোড চালায় |
প্রসঙ্গ পদ্ধতি
| পদ্ধতি | ব্যাখ্যা |
|---|---|
| vm.createContext([contextObject][, options]) | একটি নতুন পরিবেশ তৈরি করে যা স্ক্রিপ্ট চালানোর জন্য ব্যবহার করা যেতে পারে |
| vm.isContext(object) | একটি বস্তু প্রাসঙ্গিক কিনা তা পরীক্ষা করে |
| vm.runInContext(code, contextObject[, options]) | প্রদত্ত পরিবেশে কোড কম্পাইল করে এবং রান করে |
| vm.runInNewContext(code[, contextObject][, options]) | একটি নতুন পরিবেশে কোড কম্পাইল করে এবং চালায় |
| vm.runInThisContext(code[, options]) | বর্তমান প্রেক্ষাপটে কোডটি কম্পাইল এবং রান করে |
স্ক্রিপ্ট তৈরি এবং কম্পাইল করা
ভাল পারফরম্যান্সের জন্য যখন আপনাকে একই কোড একাধিকবার চালানোর প্রয়োজন হয়, আপনি স্ক্রিপ্ট ক্লাস ব্যবহার করে এটি প্রি-কম্পাইল করতে পারেন:
const vm = require('vm');
// Compile the script once
const script = new vm.Script('x += 40; let z = 30;');
// Create multiple contexts
const context1 = { x: 10 };
const context2 = { x: 20 };
// Contextify the objects
vm.createContext(context1);
vm.createContext(context2);
// Run the same script in different contexts
script.runInContext(context1);
script.runInContext(context2);
console.log(context1); // Outputs: { x: 50, z: 30 }
console.log(context2); // Outputs: { x: 60, z: 30 }
দ্রষ্টব্য:
আলাদাভাবে স্ক্রিপ্ট কম্পাইল করা আরও কার্যকর যখন আপনাকে একই কোড একাধিকবার চালাতে হবে কারণ পার্সিং এবং কম্পাইলেশন ধাপগুলি শুধুমাত্র একবারই ঘটে।
কোড চালানোর বিভিন্ন উপায়
1. runInContext
পূর্বে তৈরি পরিবেশে কোড চালানো হচ্ছে:
const vm = require('vm');
const context = { value: 10 };
vm.createContext(context);
// Run directly
vm.runInContext('value += 5', context);
console.log(context.value); // 15
// Compile then run
const script = new vm.Script('value *= 2');
script.runInContext(context);
console.log(context.value); // 30
2. runInNewContext
একটি নতুন পরিবেশ তৈরি করে এবং এতে কোড চালায়:
const vm = require('vm');
// No need to call createContext first
const context = { value: 10 };
vm.runInNewContext('value += 5; result = value * 2;', context);
console.log(context); // { value: 15, result: 30 }
3. runInThisContext
বর্তমান V8 প্রসঙ্গে কোড চালানো হচ্ছে (যেমন eval কিন্তু নিরাপদ):
const vm = require('vm');
// Define a variable in the current scope
const locallet = 20;
let result;
// This won't have access to localVar
vm.runInThisContext('result = (typeof locallet !== "undefined" ? locallet : "not defined")');
console.log(result); // 'not defined'
// But it can access globals
global.globallet = 30;
vm.runInThisContext('result = globalVar');
console.log(result); // 30
// Compare with eval, which CAN access local variables
eval('result = localVar');
console.log(result); // 20
দ্রষ্টব্য:
runInThisContext ইভালের অনুরূপ, কিন্তু যে সুযোগ থেকে এটি বলা হয় সেখানে স্থানীয় ভেরিয়েবলগুলিতে অ্যাক্সেস নেই। এটি এটিকে কিছুটা নিরাপদ করে তোলে কারণ এটি স্থানীয় ভেরিয়েবলগুলিকে প্রভাবিত করে কোড ইনজেকশন প্রবেশের ঝুঁকি হ্রাস করে।
টাইমআউট বিকল্পের সাথে কাজ করা
অন্তহীন লুপ বা দীর্ঘ-চলমান স্ক্রিপ্টগুলি প্রতিরোধ করতে স্ক্রিপ্ট সম্পাদনের জন্য একটি সময়সীমা সেট করা যেতে পারে:
const vm = require('vm');
const context = { result: 0 };
vm.createContext(context);
try {
// This should timeout after 1000ms (1 second)
vm.runInContext(`
let counter = 0;
while (true) {
counter++;
result = counter;
}
`, context, { timeout: 1000 });
} catch (err) {
console.error(`Execution timed out: ${err.message}`);
console.log(`Results before timeout: counter reached ${context.result}`);
}
সতর্কতা:
টাইমআউট বিকল্পটি গ্যারান্টি দেয় না যে নির্দিষ্ট সময়ে অপারেশনটি সঠিকভাবে শেষ হবে। প্রকৃত সময়সীমা সামান্য পরিবর্তিত হতে পারে।
Node.js কোর মডিউল অ্যাক্সেস নিয়ন্ত্রণ
ডিফল্টরূপে, Node.js কোর মডিউলের VM পরিবেশে চলমান কোডে অ্যাক্সেস নেই। আপনি কোন মডিউল উপলব্ধ তা নিয়ন্ত্রণ করতে পারেন:
const vm = require('vm');
const fs = require('fs');
// Create a sandbox with controlled access to core modules
const sandbox = {
// Allow limited access to console
console: {
log: console.log,
error: console.error
},
// Provide controlled access to fs module
fs: {
readFileSync: fs.readFileSync
},
// Custom utility
util: {
add: (a, b) => a + b,
multiply: (a, b) => a * b
},
// No access to process, child_process, etc.
};
vm.createContext(sandbox);
// Run code with limited access
try {
vm.runInContext(`
// We can use the allowed methods
console.log('Running in sandbox');
console.log('2 + 3 =', util.add(2, 3));
// Try to read a safe file
try {
const content = fs.readFileSync('example.txt', 'utf8');
console.log('File content:', content);
} catch (err) {
console.error('File read error:', err.message);
}
// Try to access process (should fail)
try {
console.log('Process info:', process.version);
} catch (err) {
console.error('Cannot access process:', err.message);
}
`, sandbox);
} catch (err) {
console.error('Sandbox execution failed:', err);
}
সতর্কতা:
যদিও আপনি নির্দিষ্ট মডিউলগুলিতে অ্যাক্সেস সীমাবদ্ধ করতে পারেন, এই পদ্ধতিটি সম্পূর্ণ নিরাপদ নয়। একজন দৃঢ়প্রতিজ্ঞ আক্রমণকারী এখনও স্যান্ডবক্স থেকে পালানোর উপায় খুঁজে পেতে পারে। সত্যিকারের নিরাপদ স্যান্ডবক্সিংয়ের জন্য, অতিরিক্ত বিচ্ছিন্নতা কৌশল বা বিশেষ লাইব্রেরি বিবেচনা করুন।
একটি সাধারণ টেমপ্লেট ইঞ্জিন তৈরি করা
ভিএম মডিউলটি একটি সাধারণ টেমপ্লেট মেশিন তৈরি করতে ব্যবহার করা যেতে পারে:
const vm = require('vm');
function renderTemplate(template, data) {
// Create template function - replace {{ let }} with values
const templateScript = `
function template(data) {
let output = \`${template.replace(/\{\{\s*(\w+)\s*\}\}/g, '${data.$1}')}\`;
return output;
}
template(data);
`;
// Create a context with the data
const context = { data };
vm.createContext(context);
// Execute the template function
return vm.runInContext(templateScript, context);
}
// Example usage
const template = `
{{ title }}
{{ title }}
Welcome, {{ name }}!
Today is {{ date }}
`;
const data = {
title: 'My Template Page',
name: 'User',
date: new Date().toLocaleDateString()
};
const rendered = renderTemplate(template, data);
console.log(rendered);
দ্রষ্টব্য:
এই উদাহরণটি একটি সাধারণ ব্যবহারের ক্ষেত্রে দেখায় যেখানে উৎপাদন টেমপ্লেট ইঞ্জিন যেমন হ্যান্ডেলবার বা EJS খুব শক্তিশালী এবং সুরক্ষিত। এই উদাহরণটি ইনজেকশন এন্ট্রি আক্রমণের জন্য ঝুঁকিপূর্ণ যদি ব্যবহারকারীর ডেটা সঠিকভাবে এস্কেপ করা হয়।
একটি প্লাগইনের বিন্যাস তৈরি করা
VM মডিউল প্লাগইন কনফিগারেশন তৈরি করার জন্য দরকারী যেখানে প্লাগইনগুলি লোড করা যায় এবং বিচ্ছিন্নভাবে চালানো যায়:
const vm = require('vm');
const fs = require('fs');
const path = require('path');
class PluginSystem {
constructor() {
this.plugins = new Map();
this.api = {
version: '1.0.0',
registerHook: this.registerHook.bind(this),
utils: {
add: (a, b) => a + b,
multiply: (a, b) => a * b,
formatDate: (date) => new Date(date).toLocaleDateString()
}
};
this.hooks = {
init: [],
process: [],
shutdown: []
};
}
// Register a plugin hook
registerHook(hookName, callback) {
if (this.hooks[hookName]) {
this.hooks[hookName].push(callback);
console.log(`Registered ${hookName} hook`);
} else {
console.error(`Invalid hook name: ${hookName}`);
}
}
// Load a plugin from file
loadPlugin(pluginName, pluginCode) {
try {
console.log(`Loading plugin: ${pluginName}`);
// Create a sandbox for this plugin
const sandbox = {
console: {
log: (msg) => console.log(`[${pluginName}] ${msg}`),
error: (msg) => console.error(`[${pluginName}] ${msg}`)
},
setTimeout,
clearTimeout,
api: this.api
};
// Create context and run the plugin code
const context = vm.createContext(sandbox);
vm.runInContext(pluginCode, context);
// Store the loaded plugin
this.plugins.set(pluginName, {
name: pluginName,
sandbox
});
console.log(`Successfully loaded plugin: ${pluginName}`);
} catch (err) {
console.error(`Error loading plugin ${pluginName}:`, err.message);
}
}
// Run all hooks of a specific type
async runHooks(hookName, data) {
console.log(`Running ${hookName} hooks...`);
for (const hook of this.hooks[hookName]) {
try {
const result = await hook(data);
console.log(`Hook result:`, result);
} catch (err) {
console.error(`Error in ${hookName} hook:`, err.message);
}
}
}
// Load all plugins from a directory
loadPluginsFromDirectory(directory) {
try {
const files = fs.readdirSync(directory);
for (const file of files) {
if (file.endsWith('.js')) {
const pluginName = path.basename(file, '.js');
const pluginPath = path.join(directory, file);
const pluginCode = fs.readFileSync(pluginPath, 'utf8');
this.loadPlugin(pluginName, pluginCode);
}
}
} catch (err) {
console.error('Error loading plugins directory:', err.message);
}
}
// Run the plugin system
async run(data) {
await this.runHooks('init', data);
await this.runHooks('process', data);
await this.runHooks('shutdown', data);
}
}
// Example plugin code (normally this would be in a separate file)
const examplePlugin = `
// Register initialization hook
api.registerHook('init', async (data) => {
console.log('Plugin initializing with data:', data);
return 'Initialization complete';
});
// Register processing hook
api.registerHook('process', async (data) => {
console.log('Processing data');
return {
processed: true,
sum: api.utils.add(data.x, data.y),
product: api.utils.multiply(data.x, data.y),
date: api.utils.formatDate(new Date())
};
});
// Register shutdown hook
api.registerHook('shutdown', async () => {
console.log('Plugin shutting down');
return 'Shutdown complete';
});
console.log('Plugin loaded with API version', api.version);
`;
// Create and run the plugin system
(async () => {
const system = new PluginSystem();
// Load plugins
system.loadPlugin('example', examplePlugin);
// You could also load from a directory
// system.loadPluginsFromDirectory('./plugins');
// Run the system
await system.run({ x: 5, y: 10 });
})();
সেরা অনুশীলন এবং নিরাপত্তা ধারণা
নিরাপত্তা সেরা অনুশীলন
কর্মক্ষমতা সেরা অনুশীলন
ভিএম প্যাকেজ বনাম ইভাল()
VM মডিউলটি eval() ব্যবহার করে বিভিন্ন সুবিধা প্রদান করে:
| বৈশিষ্ট্য | ভিএম প্যাকেজ | eval() |
|---|---|---|
| স্থানীয় ভেরিয়েবল অ্যাক্সেস | না (RunInThis Context সহ) | হ্যাঁ |
| আলাদা করা | আরও ভাল (ব্যক্তিগত প্রসঙ্গ) | না (একই প্রসঙ্গ) |
| নিরাপত্তা | ভাল (নিয়ন্ত্রিত পরিবেশ) | খারাপ (সব অ্যাক্সেসযোগ্য) |
| পুনরাবৃত্তি অপারেশন জন্য কর্মক্ষমতা | সেরা (প্রি-প্যাকেজ করা যেতে পারে) | খারাপ (প্রতিবার কম্পাইল করে) |
| চলাচলের উপর নিয়ন্ত্রণ | এছাড়াও (টাইমআউট, ইত্যাদি) | কম |
VM প্যাকেজের সীমাবদ্ধতা
সতর্কতা:
নিরাপত্তা-সমালোচনামূলক অ্যাপ্লিকেশনগুলির জন্য, আরও শক্তিশালী স্যান্ডবক্সিং সমাধান বিবেচনা করুন যেমন চাইল্ড_প্রসেস প্যাকেজ, পাত্রে বা বিশেষায়িত লাইব্রেরি যেমন vm2 সহ পৃথক প্রক্রিয়া।
সারাংশ
Node.js VM V8 JavaScript . :
অবিশ্বস্ত কোড চালানোর জন্য সম্পূর্ণ নিরাপত্তা সমাধান না হলেও, VM মডিউলটি eval() এর চেয়ে বেশি বিচ্ছিন্নতা প্রদান করে এবং Node.js অ্যাপ্লিকেশনের মধ্যে জাভাস্ক্রিপ্ট মূল্যায়নের জন্য এটি একটি মূল্যবান টুল।
উন্নত পরিবেশ ব্যবস্থাপনা
কাস্টম গ্লোবাল এবং মডিউলগুলির সাথে কীভাবে জটিল VM পরিবেশ তৈরি এবং পরিচালনা করবেন তা শিখুন:
1. গ্লোবাল ভেরিয়েবল সহ একটি কাস্টম পরিবেশ তৈরি করা
const vm = require('vm');
const util = require('util');
// Create a custom context with specific global variables
const context = {
console: {
log: (...args) => {
// Custom console.log implementation
process.stdout.write('Custom Log: ' + util.format(...args) + '\n');
},
error: console.error,
warn: console.warn,
info: console.info
},
// Add custom utilities
utils: {
formatDate: () => new Date().toISOString(),
generateId: () => Math.random().toString(36).substr(2, 9)
},
// Add a safe require function
require: (moduleName) => {
const allowedModules = ['path', 'url', 'util'];
if (!allowedModules.includes(moduleName)) {
throw new Error(`Module '${moduleName}' is not allowed`);
}
return require(moduleName);
}
};
// Contextify the object
vm.createContext(context);
// Run code in the custom context
const code = `
console.log('Current time:', utils.formatDate());
console.log('Generated ID:', utils.generateId());
try {
const fs = require('fs'); // This will throw an error
} catch (err) {
console.error('Security error:', err.message);
}
// This will work as it's an allowed module
const path = require('path');
console.log('Current directory:', path.dirname('/path/to/file.txt'));
`;
try {
vm.runInContext(code, context, { filename: 'custom-context.js' });
} catch (err) {
console.error('Script execution failed:', err);
}
নিরাপত্তা সেরা অনুশীলন
একটি VM ক্লাস্টার ব্যবহার করার সময়, নিরাপত্তা আপনার প্রথম অগ্রাধিকার হওয়া উচিত। এখানে কিছু সেরা অনুশীলন রয়েছে:
const vm = require('vm');
const { execSync } = require('child_process');
// UNSAFE: Directly executing untrusted code
function unsafeEval(code) {
// This is dangerous as it has access to the entire Node.js environment
return vm.runInThisContext(code);
}
// SAFER: Isolated context with limited access
function safeEval(code, timeout = 1000) {
// Create a context with only the necessary globals
const context = {
console: {
log: console.log,
error: console.error
},
// Add safe utilities
Math: Object.create(null),
JSON: {
parse: JSON.parse,
stringify: JSON.stringify
},
// Add a safe setTimeout with limits
setTimeout: (fn, delay) => {
if (delay > 1000) delay = 1000; // Cap delay at 1 second
return setTimeout(fn, delay);
}
};
// Copy safe methods from Math
Object.getOwnPropertyNames(Math)
.filter(prop => typeof Math[prop] === 'function')
.forEach(prop => {
context.Math[prop] = Math[prop];
});
// Create the context without prototype access
const sandbox = vm.createContext(context, {
name: 'sandbox',
codeGeneration: {
strings: false,
wasm: false
}
});
// Run the code with a timeout
try {
const script = new vm.Script(`
(function() {
"use strict";
${code}
})();
`, {
filename: 'sandbox.js',
lineOffset: 0,
displayErrors: true,
timeout: timeout,
microtaskMode: 'afterEvaluate'
});
return script.runInContext(sandbox, { timeout });
} catch (err) {
console.error('Script execution failed:', err.message);
throw new Error('Script execution failed');
}
}
// Example of safe evaluation
try {
const result = safeEval(`
function add(a, b) { return a + b; }
add(2, 3);
`);
console.log('Safe evaluation result:', result); // Outputs: 5
// This will be caught by our safe evaluator
safeEval('process.exit(1)');
} catch (err) {
console.error('Caught error:', err.message);
}
// Example of security risks
console.log('\nTesting security risks:');
try {
console.log('1. Accessing process:');
safeEval('process.versions.node');
} catch (err) {
console.log('✓ Blocked access to process object');
}
try {
console.log('2. Infinite loop:');
safeEval('while(true){}');
} catch (err) {
console.log('✓ Caught infinite loop with timeout');
}
try {
console.log('3. Prototype pollution:');
safeEval('({}).constructor.prototype.polluted = true');
console.log('✓ Blocked prototype pollution');
} catch (err) {
console.log('✓ Blocked prototype pollution');
}
গুরুত্বপূর্ণ:
একটি VM ব্লক একটি নিরাপত্তা সীমানা নয়। অবিশ্বস্ত কোড চালানোর জন্য ডকার, AWS Lambda, বা Google ক্লাউড ফাংশনগুলির মতো ডেডিকেটেড স্যান্ডবক্সিং সমাধানগুলি ব্যবহার করার কথা বিবেচনা করুন৷
কর্মক্ষমতা অপ্টিমাইজেশান
এই কৌশলগুলির সাথে ভিএম কর্মক্ষমতা অপ্টিমাইজ করুন:
const vm = require('vm');
const { performance, PerformanceObserver } = require('perf_hooks');
// 1. Compile once, run many times
const expensiveCalculation = new vm.Script(`
function calculate(n) {
let result = 0;
for (let i = 0; i < n; i++) {
result += Math.sqrt(i) * Math.PI;
}
return result;
}
// Return the function reference
calculate;
`);
// Create a context
const context = { Math };
vm.createContext(context);
// Run once to get the function
const calculate = expensiveCalculation.runInContext(context);
// Now we can call the function multiple times without recompiling
console.log('Result (n=1000):', calculate(1000));
console.log('Result (n=2000):', calculate(2000));
// 2. Use code caching for better performance
const cache = new Map();
function compileWithCache(code, filename) {
if (cache.has(code)) {
console.log(`Using cached script for ${filename}`);
return cache.get(code);
}
console.log(`Compiling script for ${filename}`);
const script = new vm.Script(code, {
filename,
cachedData: null, // Will be populated on first run
produceCachedData: true
});
cache.set(code, script);
return script;
}
// 3. Measure performance
function measurePerformance() {
const obs = new PerformanceObserver((items) => {
const entry = items.getEntries()[0];
console.log(`\nExecution time for ${entry.name}: ${entry.duration.toFixed(2)}ms`);
performance.clearMarks();
});
obs.observe({ entryTypes: ['measure'] });
// Test with different script sizes
const smallScript = new vm.Script('let sum = 0; for (let i = 0; i < 1000; i++) sum += i; return sum;');
const largeScript = new vm.Script(`
function processData(data) {
return data.map(x => ({
...x,
processed: true,
timestamp: Date.now(),
hash: require('crypto').createHash('md5').update(JSON.stringify(x)).digest('hex')
}));
}
// Process sample data
const data = Array(1000).fill(null).map((_, i) => ({ id: i, value: Math.random() }));
return processData(data);
`);
// Measure execution
performance.mark('small-start');
smallScript.runInThisContext();
performance.mark('small-end');
performance.mark('large-start');
largeScript.runInThisContext();
performance.mark('large-end');
performance.measure('Small script execution', 'small-start', 'small-end');
performance.measure('Large script execution', 'large-start', 'large-end');
}
// Run performance test
measurePerformance();
// 4. Reuse contexts for better performance
function createOptimizedContext() {
const context = {
// Only include what's necessary
console: {
log: console.log,
error: console.error
},
// Add required globals
setTimeout,
clearTimeout,
// Add custom utilities
utils: {
formatNumber: n => new Intl.NumberFormat().format(n),
formatDate: d => d.toISOString()
}
};
// Create context once
vm.createContext(context);
return context;
}
// Reuse the same context for multiple scripts
const sharedContext = createOptimizedContext();
// Run multiple scripts with the same context
function runWithSharedContext(code) {
try {
const script = new vm.Script(code);
return script.runInContext(sharedContext);
} catch (err) {
console.error('Script execution failed:', err);
throw err;
}
}
// Example usage
const script1 = 'console.log("Script 1:", utils.formatNumber(1234567.89));';
const script2 = 'console.log("Script 2:", utils.formatDate(new Date()));';
runWithSharedContext(script1);
runWithSharedContext(script2);